package com.jeecg.demo.util;

import java.beans.BeanInfo;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jeecgframework.web.cgform.common.CgAutoListConstant;
import org.jeecgframework.web.cgform.entity.config.CgFormFieldEntity;
import org.jeecgframework.web.cgform.service.autolist.ConfigServiceI;
import org.jeecgframework.web.cgform.service.config.CgFormFieldServiceI;
import org.jeecgframework.web.system.pojo.base.DictEntity;
import org.jeecgframework.web.system.service.SystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 数据绑定助手
 */
@Component
public class DataBindUtil {
	@Autowired
	private SystemService systemService;
	@Autowired
	private ConfigServiceI configService;
	@Autowired
	private CgFormFieldServiceI cgFormFieldService;
	
	String[] filterFields = {"createName", "createBy", "createDate", "updateName", "updateBy", 
			"updateDate", "sysOrgCode", "sysCompanyCode", "bpmStatus"};

	/**
	 * 绑定对象列表字典名称
	 * @param taskList 对象列表
	 * @param configId 配置信息ID
	 * @return
	 * @throws Exception
	 */
	public List<Map<String, Object>> BindDicNameList(List<?> taskList, String configId) throws Exception {
		List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
		
		List<CgFormFieldEntity> beans = getDicFieldEntity(configId);

		for (Object item : taskList) {
			Map<String, Object> resultItem = BindDicName(item, configId, beans);
			resultList.add(resultItem);
		}
		
		return resultList;
	}
	
	/**
	 * 绑定对象字典名称
	 * @param task 数据对象
	 * @param configId 配置信息ID
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> BindDicName(Object task, String configId) throws Exception {
		return BindDicName(task, configId, null);
	}
	
	/**
	 * 绑定对象字典名称
	 * @param task 数据对象
	 * @param configId 配置信息ID
	 * @param beans 字段信息
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> BindDicName(Object task, String configId, List<CgFormFieldEntity> beans) throws Exception {
		Map<String, Object> result = objectToMap(task);

		if (beans == null) {
			beans = getDicFieldEntity(configId);
		}

		for (CgFormFieldEntity item : beans) {
			String fieldName = convertDatabaseFieldNameToMapFieldName(item.getFieldName());
			
			if (result.get(fieldName) != null) {
				String dicName = getDictName(item.getDictTable(), item.getDictField(), item.getDictText(), 
						result.get(fieldName).toString());
				
				if (null!= dicName && !dicName.equals("")) {
					result.put(fieldName + "DicName", dicName);
				}
			}
		}
		
		// 过滤不需要的字段
		for (String filterItem : filterFields) {
			if (result.containsKey(filterItem)) {
				result.remove(filterItem);
			}
		}
		
		return result;
	}
	
	/**
	 * 根据字典属性返回对应的字典值
	 * @return
	 */
	private String getDictName(String dicTable, String dicCode,String dicText, String dicValue) {
		String result = "";
		List<DictEntity> dictList = null;
		
		// 查询数据字典
		dictList = systemService.queryDict(dicTable, dicCode, dicText);
		
		// 根据字典编码查询数据字典对应名称
		if (dictList != null && dictList.size() > 0) {
			for (DictEntity item : dictList) {
				if (item.getTypecode().equals(dicValue)) {
					result = item.getTypename();
					break;
				}
			}
		}
		
		return result;
	}

	/**
	 * 查询有关联字典表字段信息
	 * @param configId
	 * @return
	 */
	private List<CgFormFieldEntity> getDicFieldEntity(String configId) {
		List<CgFormFieldEntity> beans = getCgFormFieldEntity(configId);
		List<CgFormFieldEntity> beansFilter = new ArrayList<CgFormFieldEntity>();
		
		// 只添加有关联字表的字段信息
		for (CgFormFieldEntity item : beans) {
			if (!item.getShowType().equals("popup")) {
				if (!item.getDictField().equals("")) {
					beansFilter.add(item);
				}
			}
		}
		return beansFilter;
	}
	
	/**
	 * 查询字段信息
	 * @param configId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private List<CgFormFieldEntity> getCgFormFieldEntity(String configId) {
		String jversion = cgFormFieldService.getCgFormVersionByTableName(configId);
		Map<String, Object> configs = configService.queryConfigs(configId, jversion);
		List<CgFormFieldEntity> beans = (List<CgFormFieldEntity>) configs.get(CgAutoListConstant.FILEDS);

		return beans;
	}
	
	/**
	 * 将数据库字段名称转换为Map字段名称
	 * @param baseFieldName
	 * @return
	 */
	private String convertDatabaseFieldNameToMapFieldName(String baseFieldName) {
		String fieldName = baseFieldName;

		while (fieldName.indexOf("_") > 0) {
			int findex = fieldName.indexOf("_");
			
			if (findex < fieldName.length()-1) {
				fieldName = fieldName.substring(0, findex) 
				+ fieldName.substring(findex+1, findex+2).toUpperCase() 
				+ fieldName.substring(findex+2);
			} else {
				break;
			}
		}
		
		return fieldName;
	}
	
	/**
	 * 将数据对象转换为Map
	 * @param obj 数据对象
	 * @return
	 * @throws Exception
	 */
	private Map<String, Object> objectToMap(Object obj) throws Exception {    
        if(obj == null)  
            return null;      
  
        Map<String, Object> map = new HashMap<String, Object>();   
  
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());    
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();    
        for (PropertyDescriptor property : propertyDescriptors) {    
            String key = property.getName();    
            if (key.compareToIgnoreCase("class") == 0) {   
                continue;  
            }  
            Method getter = property.getReadMethod();  
            Object value = getter!=null ? getter.invoke(obj) : null;  
            map.put(key, value);  
        }    
  
        return map;  
    }
}
